package observer

import (
	"fmt"
	"sync"
)

type Subject struct {
	observers []Observer
	mu        sync.Mutex
	msg       string
}

type Observer interface {
	Update(sub *Subject)
}

func (s *Subject) Attach(o Observer) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.observers = append(s.observers, o)
}

func (s *Subject) Notify() {
	for _, o := range s.observers {
		o.Update(s)
	}
}

func (s *Subject) UpdateMsg(context string) {
	s.msg = context
	s.Notify()
}

func NewSubject() *Subject {
	return &Subject{
		observers: make([]Observer, 0),
		msg:       "",
	}
}

type Reader struct {
	name string
}

func (r *Reader) Update(s *Subject) {
	fmt.Printf("%s receive message:%s\n", r.name, s.msg)
}

func NewReader(name string) *Reader {
	return &Reader{
		name: name,
	}
}
